/**
 * 一些 js 注入
 */

import jQuery from 'jquery'
import formatter from '@/libs/framework/formatter';
import _ from 'lodash';
import request from '@/utils/request';

let Injection = {
  // 加载一些扩展内容
  injectExtension(globalObject) {

    globalObject.String.prototype.format = function () {
      var str = this;
      for (var i = 0; i < arguments.length; i++) {
        var re = new RegExp('\\{' + (i) + '\\}', 'gm');
        str = str.replace(re, arguments[i]);
      }
      return str;
    }

    globalObject.String.prototype.lTrim = function (s) {
      s = (s ? s : "\\s"); //没有传入参数的，默认去空格
      s = ("(" + s + ")");
      var reg_lTrim = new RegExp("^" + s + "*", "g"); //拼正则
      return this.replace(reg_lTrim, "");
    };

    globalObject.String.prototype.rTrim = function (s) {
      s = (s ? s : "\\s");
      s = ("(" + s + ")");
      var reg_rTrim = new RegExp(s + "*$", "g");
      return this.replace(reg_rTrim, "");
    };

    globalObject.String.prototype.trim = function (s) {
      if (s) {
        s = (s ? s : "\\s");
        s = ("(" + s + ")");
        var reg_trim = new RegExp("(^" + s + "*)|(" + s + "*$)", "g");
        return this.replace(reg_trim, "");
      } else {
        return this.replace(/(^\s*)|(\s*$)/g, "");
      }
    };



    globalObject.String.prototype.startWith = function (s) {
      return this.indexOf(s) == 0;
    }


    globalObject.String.prototype.toHump = function () {
      let result = this;
      if (result) {
        if (result.indexOf("_") > -1) {
          return result.toLowerCase().replace(/\_(\w)/g, function (all, letter) {
            return letter.toUpperCase();
          });
        } else if (result == result.toUpperCase()) {
          return result.toLowerCase();
        }

      }
      return result ? result.toString() : result;
    }

    globalObject.String.prototype.toLine = function () {
      let result = this;
      if (result && result != result.toUpperCase()) {
        return result.replace(/([A-Z])/g, "_$1").toUpperCase();
      }
      return result;
    }

    globalObject.Array.prototype.S = globalObject.String.fromCharCode(2);
    globalObject.Array.prototype.exists = function (e) {
      if (this.join == undefined) {
        return false;
      }
      var r = new RegExp(this.S + e + this.S);
      return (r.test(this.S + this.join(this.S) + this.S));
    }
    globalObject.Array.prototype.indexOf = function (val) {
      for (var i = 0; i < this.length; i++) {
        if (this[i] == val) return i;
      }
      return -1;
    };
    globalObject.Array.prototype.remove = function (val) {
      var index = this.indexOf(val);
      if (index > -1) {
        this.splice(index, 1);
      }
    };
    globalObject.Array.prototype.removeAt = function (i) {
      var index = i
      if (index > -1) {
        this.splice(index, 1);
      }
    };
    globalObject.Array.prototype.insertAt = function (i, elem) {
      this.splice(i, 0, elem);
    }
    globalObject.Array.prototype.unique = function () {
      var result = [],
        hash = {};
      for (var i = 0; i < this.length; i++) {
        var elem = this[i];
        if (!hash[elem]) {
          result.push(elem);
          hash[elem] = true;
        }
      }
      return result;
    }

    //对Date的扩展，将 Date 转化为指定格式的String
    //月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
    //年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
    //例子：
    //(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
    //(new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
    globalObject.Date.prototype.format = function (fmt) { // author: meizz
      var o = {
        "M+": this.getMonth() + 1, // 月份
        "d+": this.getDate(), // 日
        "h+": this.getHours(), // 小时
        "m+": this.getMinutes(), // 分
        "s+": this.getSeconds(), // 秒
        "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
        "S": this.getMilliseconds()
        // 毫秒
      };
      if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
          .substr(4 - RegExp.$1.length));
      for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt))
          fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) :
            (("00" + o[k]).substr(("" + o[k]).length)));
      return fmt;
    }


    globalObject.Math.uuid = function (len, radix) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
        uuid = [],
        i;
      radix = radix || chars.length;

      if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
      } else {
        // rfc4122, version 4 form
        var r;

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
        uuid[14] = '4';

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | Math.random() * 16;
            uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
          }
        }
      }

      return uuid.join('');
    };

    // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
    // by minimizing calls to random()
    globalObject.Math.uuidFast = function () {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
        uuid = new Array(36),
        rnd = 0,
        r;
      for (var i = 0; i < 36; i++) {
        if (i == 8 || i == 13 || i == 18 || i == 23) {
          uuid[i] = '-';
        } else if (i == 14) {
          uuid[i] = '4';
        } else {
          if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0;
          r = rnd & 0xf;
          rnd = rnd >> 4;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
      return uuid.join('');
    };

    // A more compact, but less performant, RFC4122v4 solution:
    globalObject.Math.uuidCompact = function () {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    };

    globalObject.String.prototype.endsWith = function (searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.lastIndexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
    };

    globalObject.String.prototype.startsWith = function (searchString, position) {
      position = position || 0;
      return this.substr(position, searchString.length) === searchString;
    };

    globalObject.String.prototype.format = function (args) {
      if (arguments.length > 0) {
        var result = this;
        if (arguments.length == 1 && typeof (args) == "object") {
          for (var key in args) {
            var reg = new RegExp("({" + key + "})", "g");
            result = result.replace(reg, args[key]);
          }
        } else {
          for (var i = 0; i < arguments.length; i++) {
            var reg = new RegExp("({[" + i + "]})", "g");
            result = result.replace(reg, arguments[i] || "");
          }
        }
        return result;
      } else {
        return this;
      }
    }

    globalObject.String.prototype.toHump = function () {
      let result = this;
      if (result) {
        if (result.indexOf("_") > -1) {
          return result.toLowerCase().replace(/\_(\w)/g, function (all, letter) {
            return letter.toUpperCase();
          });
        } else if (result == result.toUpperCase()) {
          return result.toLowerCase();
        }

      }
      return result;
    }


    globalObject.numberToFixed = function (num, radix = 2, formatNaN = '') {
      if (num === '' || num === undefined || num === null) {
        return formatNaN;
      }
      let re = num.toFixed(radix);
      if (Math.abs(re) == 0) {
        return Math.abs(re).toFixed(radix);
      } else {
        return re;
      }
    }

    globalObject.Array.prototype.distinct = function () {
      var h = {};
      var arr = [];
      for (var i = 0; i < this.length; i++) {
        if (!h[this[i]]) {
          h[this[i]] = true;
          arr.push(this[i]);
        }
      }
      return arr;
    }

    globalObject.Math.uuid = function (len, radix) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
        uuid = [],
        i;
      radix = radix || chars.length;

      if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
      } else {
        // rfc4122, version 4 form
        var r;

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
        uuid[14] = '4';

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | Math.random() * 16;
            uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
          }
        }
      }

      return uuid.join('');
    };

    // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
    // by minimizing calls to random()
    globalObject.Math.uuidFast = function () {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
        uuid = new Array(36),
        rnd = 0,
        r;
      for (var i = 0; i < 36; i++) {
        if (i == 8 || i == 13 || i == 18 || i == 23) {
          uuid[i] = '-';
        } else if (i == 14) {
          uuid[i] = '4';
        } else {
          if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0;
          r = rnd & 0xf;
          rnd = rnd >> 4;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
      return uuid.join('');
    };

    // A more compact, but less performant, RFC4122v4 solution:
    globalObject.Math.uuidCompact = function () {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    };
  },
  injectJq(globalObject) {
    globalObject.jQuery = globalObject.$ = jQuery;

    globalObject.$.getQueryString = function (name, top = true) {
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
      var obj = top ? window : globalObject;
      var r = obj.location.search.substr(1).match(reg);
      if (r != null)
        return decodeURI(r[2]);
      return null;
    }
  },
  injectFormatter(globalObject) {
    globalObject.formatter = formatter;
  },
  injectLodash(globalObject) {
    globalObject._ = _;
  },
  injectRequest(globalObject) {
    globalObject.$request = request;
  },

  /**
   * smartform相关的js内容注入，统一注入入口
   * @param {*} globalObject iframe 的window对象
   */
  injectSmartformJs(globalObject) {
    this.injectExtension(globalObject);
    this.injectJq(globalObject);
    this.injectFormatter(globalObject);
    this.injectLodash(globalObject);
    this.injectRequest(globalObject);
  }

};

export default Injection;
